package com.itheima.app.aspectj;
 
import com.itheima.app.annotation.MyLog;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.Log;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;


@Aspect
@Component
public class LogAspect {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 此处的切点是注解的方式，也可以用包名的方式达到相同的效果
     * '@Pointcut("execution(* com.wwj.springboot.service.impl.*.*(..))")'
     */
    @Pointcut("@annotation(com.itheima.app.annotation.MyLog)")
    public void operationLog(){}
 
 
    /**
     * 环绕增强，相当于MethodInterceptor
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object res = null;
        long time = System.currentTimeMillis();
        try {
            res =  joinPoint.proceed();
            time = System.currentTimeMillis() - time;
            return res;
        } finally {
            try {
                //方法执行完成后增加日志
                addOperationLog(joinPoint);
            }catch (Exception e){
                System.out.println("LogAspect 操作失败：" + e.getMessage());
                e.printStackTrace();
            }
        }
    }
 
   private void addOperationLog(JoinPoint joinPoint){
       MethodSignature signature = (MethodSignature)joinPoint.getSignature();

       Log log =new Log();
       log.setLogTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
       log.setUserId(UserHolder.get().getId());
       log.setPlace("上海");
       log.setEquipment("OnePlus8");
       MyLog annotation = signature.getMethod().getAnnotation(MyLog.class);
       if (annotation!=null){
           log.setType(annotation.operationType().getValue());
       }

       rocketMQTemplate.convertAndSend("tanhua-log",log);

    }


    @Before("operationLog()")
    public void doBeforeAdvice(JoinPoint joinPoint){
        System.out.println("进入方法前执行.....");

    }
 
    /**
     * 处理完请求，返回内容
     * @param ret
     *
    @AfterReturning(returning = "ret", pointcut = "operationLog()")
    public void doAfterReturning(Object ret) {
        System.out.println("方法的返回值 : " + ret);
    }*/
 
    /**
     * 后置异常通知
     */
    @AfterThrowing("operationLog()")
    public void throwss(JoinPoint jp){
        System.out.println("方法异常时执行.....");
    }
 
 
    /**
     * 后置最终通知,final增强，不管是抛出异常或者正常退出都会执行
     */
    @After("operationLog()")
    public void after(JoinPoint jp){
        System.out.println("方法最后执行.....");
    }
}